package com.letoken.platform.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.letoken.platform.admin.service.AppUserWalletService;
import com.letoken.platform.pub.constant.RedisKeyConstant;
import com.letoken.platform.pub.enums.LetokenApiResponseEnum;
import com.letoken.platform.pub.exception.ApiServiceException;
import com.letoken.platform.repo.app.dao.AppUserWalletMapper;
import com.letoken.platform.repo.app.po.AppUserWallet;
import com.letoken.platform.repo.app.redis.RedisConfig;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.concurrent.TimeUnit;

/**
 * @author wyl
 * @date 2023/1/1 16:23
 * @Version 1.0
 */
@Service
public class AppUserWalletServiceImpl extends ServiceImpl<AppUserWalletMapper, AppUserWallet> implements AppUserWalletService {

    @Resource
    private AppUserWalletMapper appUserWalletMapper;


    @Resource
    private RedisConfig redisConfig;


    /**
     * 修改用户金额 减传负数
     *
     * @param availableBalance 可用金额
     * @param freezeBalance    冻结金额
     * @param releasedBalance  等待释放金额
     * @param userId           用户id
     * @param tokenId          币种id
     * @return
     */
    @Override
    public int updateUserAmountByUserIDandCoin(BigDecimal availableBalance, BigDecimal freezeBalance, BigDecimal releasedBalance, Integer userId, Integer tokenId) {
        String key = RedisKeyConstant.UPDATE_APP_USER_WALLET + userId;
        int rulest;
        RedissonClient redissonClient = redisConfig.getRedisson();
        RLock rlock = redissonClient.getLock(key);
        try {
            rlock.lock(5,TimeUnit.SECONDS);
            QueryWrapper<AppUserWallet> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId).eq("token_id", tokenId);
            AppUserWallet userWallet = appUserWalletMapper.selectOne(queryWrapper);
            if (userWallet.getAvailableBalance().add(availableBalance).compareTo(BigDecimal.ZERO) < 0) {
                log.error(MessageFormat.format("流通余额{0}少于扣减金额{1}", userWallet.getAvailableBalance(), availableBalance));
                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_APP_ASSETS_002);
            }
            if (userWallet.getFreezeBalance().add(freezeBalance).compareTo(BigDecimal.ZERO) < 0) {
                log.error(MessageFormat.format("冻结余额{0}少于扣减金额{1}", userWallet.getFreezeBalance(), freezeBalance));
                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_APP_ASSETS_002);
            }
            if (userWallet.getReleasedBalance().add(releasedBalance).compareTo(BigDecimal.ZERO) < 0) {
                log.error(MessageFormat.format("待释放余额{0}少于扣减金额{1}", userWallet.getReleasedBalance(), releasedBalance));
                throw new ApiServiceException(LetokenApiResponseEnum.ERROR_APP_ASSETS_002);
            }
            rulest = appUserWalletMapper.updateUserAmountByUserIDandCoin(availableBalance, freezeBalance, releasedBalance, userWallet.getVersion(), userId, tokenId);
        } finally {
            if (rlock != null && rlock.isHeldByCurrentThread()) {
                rlock.unlock();
            }
        }
        return rulest;
    }
}
